package com.jy.rhin.parse;

import com.jy.framework.base.utils.Serializer;
import com.jy.rhin.infra.cda.CDAException;
import com.jy.rhin.model.*;
import com.jy.rhin.model.body.ertongjktj.ErTongJKTJ;
import com.jy.rhin.model.body.siwangyxzm.SiWangYXZM;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.parser.Parser;
import org.seimicrawler.xpath.JXDocument;
import org.seimicrawler.xpath.JXNode;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author 姚俊
 * @Date 2023/2/14 15:12
 * @Description CDA解析
 */
@Slf4j
public class CDAParser {

    static Map<String, Class<? extends ClinicalDocumentData>> docModels = new HashMap<>();

    static {
        docModels.put("HSDA00.01", GeRenJBXXDJ.class);
        docModels.put("HSDC00.01", JianKangTJ.class);
        docModels.put("HSDC00.02", MenZhenZY.class);
        docModels.put("HSDB02.01", ChanQianSCSF.class);
        docModels.put("HSDB02.02", ChanQianSF.class);
        docModels.put("HSDB02.03", ChanHouFS.class);
        docModels.put("HSDB02.04", ChanHouJC.class);
        docModels.put("HSDB03.01", YuFangJZ.class);
        docModels.put("HSDB03.02", ChuanRanBBG.class);
        docModels.put("HSDB04.01", GaoXueYSF.class);
        docModels.put("HSDB04.02", TangNiaoBSF.class);
        docModels.put("HSDB04.03", ZhongXingJSBDJ.class);
        docModels.put("HSDB04.04", ZhongXingJSBSF.class);
        docModels.put("HSDB01.02", XinShengErJTFS.class);
        docModels.put("HSDB01.01", ChuShengYXZM.class);
        docModels.put("HSDB03.03", SiWangYXZM.class);
        docModels.put("HSDC00.03", ZhuYuanZY.class);
        docModels.put("HSDB01.03", ErTongJKTJ.class);
        docModels.put("HSDC00.04", HuiZhenJL.class);
        docModels.put("HSDC00.05", ZhuanZhenJL.class);
    }

    String doc;
    JXDocument jxDocument;
    JXNode root;

    public CDAParser(String doc) {
        this.doc = doc;
        jxDocument = JXDocument.create(Parser.xmlParser().parseInput(doc, ""));
        root = jxDocument.selNOne("//ClinicalDocument");
    }

    public Object parse() {
        Object o = parseDataModel(getDataModelClass(root));
        log.info("{}", Serializer.serialize(o));
        return o;
    }

    <T extends ClinicalDocumentData> T parseDataModel(Class<T> dataModelCls) {
        try {
            T dataModel = dataModelCls.newInstance();
            CDAParseSupport.setAllFieldValues(root, dataModel);
            return dataModel;
        } catch (Exception e) {
            log.error("解析异常", e);
            return null;
        }
    }

    /**
     * @Description 获取CDA文档对应的数据模型
     */
    Class<? extends ClinicalDocumentData> getDataModelClass(JXNode root) {
        try {
            String code = root.selOne("//code//@code").toString();
            return docModels.get(code);
        } catch (Exception e) {
            throw new CDAException("获取CDA code错误", e);
        }
    }
}
